1. Introduction
This notebook contains a pathway and network analysis for the set of ranked genes obtained from the GEO dataset GSE157194, associated with the publication “Atopic dermatitis displays stable and dynamic skin transcriptome signatures” (Möbus et al., 2021). The goal of the study was to understand the effects of the drugs dupilumab and cyclosporine on atopic dermatitis (AD) by conducting a gene expression study using mRNA-seq data taken from biopsies of human patients.
The raw count matrix was first downloaded via GEOquery (Davis & Meltzer, 2007), and the data was cleaned to confirm that no duplicates were present. Next, the data was then filtered by gene, removing those without at least one read per million in each sample, and also by patient, removing those with incomplete data. Ensembl IDs were mapped to HUGO gene symbols using biomaRt (Durinck et al., 2009), and genes that were unable to be converted (e.g., novel genes) were removed. To normalize the data, trimmed mean of m-values was used (Robinson et al., 2010), since the assumption was that most genes were not differentially expressed. See this report for more details on the dataset, its cleaning, and its normalization.
The obtained list of genes was next used to perform a differential gene expression analysis using a quasi-likelihood model (Robinson et al., 2010), and the resulting p-values for each gene were converted to rank (using the formula \(\text{-}\hspace{-0.6mm}\log_{10}(p\text{-}value) \times \text{sign}(logFC)\)). The resulting set of ranked genes was then sorted by descending rank and written to the file rankedGeneList.rnk, which will be the starting point for GSEA. See this report for more details on the gene expression analysis (and additional over-representation analysis).
The corresponding journal entry for this notebook can be found here. We can begin by taking a look at the top and bottom of the list of ranked genes to get an idea of what the table looks like:
# Make sure the rank file exists
rankFile <- file.path(getwd(), "rankedGeneList.rnk")
if (!file.exists(rankFile)) {
stop("Rank file not found")
}
rankList <- read.table(file = rankFile,
sep = "\t",
header = TRUE,
stringsAsFactors = FALSE,
check.names = FALSE)
knitr::kable(rankList[1:5, ], type = "html")
Table 1. The first five genes in the ranked gene list.
stopIdx <- nrow(rankList)
startIdx <- stopIdx - 5
knitr::kable(rankList[startIdx:stopIdx, ], type = "html")
Table 2. The last five genes in the ranked gene list.
2. Non-Thresholded Gene Set Enrichment Analysis (GSEA)
The GSEA pre-ranked method will be used for analysis (Subramanian et al., 2005) (Mootha et al., 2003) (version 4.2.3, run locally, with the results presented here).
First, we will need a gene set file for the analysis. For this, we can download one provided by the Bader Lab (Merico et al., 2010) (see http://download.baderlab.org/EM_Genesets). These sets contain many sources (see the list here) and are updated regularly (monthly), so are ideal for this task. In particular, we will choose one for human genes, contains all GO:BP pathways (since we are mostly focused on pathways), and excludes inferred electronic annotations (since we want our analysis to be more specific or curated). As of the time of writing, the most updated version of the file that satisfies these criteria is from April 1, 2022, so this will be the version downloaded and used here (Human_GOBP_AllPathways_no_GO_iea_April_01_2022_symbol.gmt).
# Get a list of all the available gene set files
gsUrl <- "http://download.baderlab.org/EM_Genesets/current_release/Human/symbol/"
files <- RCurl::getURL(gsUrl)
conn <- textConnection(files)
contents <- readLines(conn)
close(conn)
# Find the GMT file with all GO:BP pathways and no electronic annotations
regex <- gregexpr("(?<=<a href=\")(.*.GOBP_AllPathways_no_GO_iea.*.)(.gmt)(?=\">)", contents, perl = TRUE)
gmt <- unlist(regmatches(contents, regex))
# Download the file if it has not been already
# Warning: it may download a more up-to-date gene set; if doing comparisons or trying to reproduce results, make sure
# to check the version number
gmtFile <- file.path(getwd(), gmt)
if (!file.exists(gmtFile)) {
download.file(paste(gsUrl, gmt, sep = ""), destfile = gmtFile)
}
The GSEA settings used were as follows:
Number of permutations: 1000
Collapse/Remap to gene symbols: No_Collapse
Enrichment statistic: weighted
Max size: 200
Min size: 15
Some explanations for using these parameters can be found here.
Summary of Results
The dataset has 17,747 genes, all of which were used in the analysis. The gene set had 18,536 genes, but after applying the minimum and maximum size filters, the number was reduced to 5,591 (a reduction of 12,945 sets).
For the upregulated sets:
- 1,186 gene sets were found to be upregulated (of the 5,591)
- 350 sets were significant at FDR < 0.25
- 338 sets were significantly enriched with p-value < 0.05
- 191 sets were significantly enriched with p-value < 0.01
- The top set was “PEPTIDE CHAIN ELONGATION%REACTOME DATABASE ID RELEASE 79%156902” with the following details:
- Enrichment score of 0.75145817
- Normalized enrichment score of 2.7556887
- p-value of 0.0
- FDR of 0.0
- Leading edge set has size 71
- Top gene is RPS18
For the downregulated sets:
- 4,405 gene sets were found to be downregulated
- 2,053 sets were significant at FDR < 0.25
- 1,506 sets were significantly enriched with p-value < 0.05
- 824 sets were significantly enriched with p-value < 0.01
- The top set was “HALLMARK_E2F_TARGETS%MSIGDB_C2%HALLMARK_E2F_TARGETS” with the following details:
- Enrichment score of -0.6646858
- Normalized enrichment score of -2.1820378
- p-value of 0.0
- FDR of 0.0
- Leading edge set has size 98
- Top gene is ESPL1
Comparison to Thresholded Analysis
The idea of comparing these results to the thresholded analysis (TA) (see this report) is not very straightfoward, because whereas TA only used genes that were found to be significantly differentially expressed (and it was also possible to run the analyses separately for up- and down-regulated genes), this non-thresholded analysis (NTA) used every gene, all at once, regardless of the level of differential expression. However, we can still try to compare the results, as it may provide some further insight into the observed pathways.
Looking at the upregulated genes, we see that TA found 5,027, 1,007, and 445 pathways, by GO:BP, REAC, and WikiPathways, respectively, whereas NTA only found 1,186 sets. More specifically, TA’s most significant found pathways were related to metabolic processes (e.g., “long-chain fatty acid metabolic process” and “unsaturated fatty acid metabolic process”), whereas NTA’s most significant sets were somewhat more related to translation (e.g., “VIRAL MRNA TRANSLATION” and “EUKARYOTIC TRANSLATION ELONGATION”), with metabolic processes slightly further down the list. This difference could possibly be explained by the issue noted previously; TA only used significantly upregulated genes for this part of the analysis.
Looking at the downregulated genes, we see that TA found 230, 72, and 52 pathways, by GO:BP, REAC, and WP, respectively, whereas NTA found 4,405 sets. More specifically, TA’s most significant found pathways were related to DNA replication (e.g., “cell cycle DNA replication” and “DNA-dependent DNA replication”), and NTA’s most significant sets were somewhat similar (e.g., “DNA IR-DAMANGE AND CELLULAR RESPONSE” and “DNA-TEMPLATED DNA REPLICATION”). Overall, it is possible to say that the compared results are quite similar, and to a degree, agree with each other.
3. Visualization of Gene Set Enrichment Analysis (Cytoscape)
To visualize this data as a network, Cytoscape (Shannon et al., 2003) will be used (version 3.9.1, run locally) with the EnrichmentMap (Merico et al., 2010) pipeline (Cytoscape app version 3.3.3). Other included apps are clusterMaker 2 (Morris et al., 2011) version 2.2, WordCloudd (Oesper et al., 2011) version 3.1.4, and AutoAnnotate (Kucera, 2017) version 1.3.5, all downloaded from the Cytoscape App Store (via the Cytoscape App Manager).
The GSEA output directory was loaded into EnrichmentMap with the following thresholds (which were recommended by the EnrichmentMap documentation here):
- FDR cutoff: 0.05
- p-value cutoff: 0.001
- Edge metric: Jaccard+Overlap Combined
- Edge cutoff: 0.5
This produced the following raw image (no manual adjustments or legends, hidden labels):

Figure 1. The initial enrichment map. There are 457 nodes and 1,160 edges.
Annotation
The next step is to annotate the network with clusters. AutoAnnotate (Kucera, 2017) with default parameters (plus the prevention of cluster overlap) was used to annotate the entire network. Some of the key parameters are as follows:
- Cluster options: use the clusterMaker app to define clusters
- Cluster algorithm: MCL Cluster
- Label options: use gene descriptions as the label column
- Label algorithm: WordCloud (adjacent words)
- Max words per label: 3
- Minimum word occurrence: 1
- Adjacent word bonus: 8
This produced the following image:

Figure 2. The automatically annotated enrichment map.
We notice that the maps so far are missing legends; it is not immediately clear which colours correspond to which directions of regulation. We can have the enrichment map automatically generate one, which looks like the following:
Figure 3. The automatically generated legend. Red is for upregulation while blue is for downregulation.
We can then combine the annotated map with the legend (and add a title) to create a “publication-ready” figure:

Figure 4. The complete enrichment map for the analysis, with annotated clusters, legend, and title added.
The map has quite a few significant gene sets, making the text hard to read (because there are so many clusters), so it may be helpful to open the image separately (perhaps in a new tab) when looking for specific sets or just looking at the finer details.
Another way to look at the network is to collapse all of the clusters to make a theme network. This may help in identifying the major themes present, which can further solidify the understanding of relevant pathways, or even to possibly find novel ones.

Figure 5. The theme network generated by collapsing the enrichment map.
After collapsing the clusters in the enrichment map, we can see several key themes present, including DNA repair/ replication, transcription/translation, metabolism/catabolism, extracellular structure, and cell cycle. All of these themes agree with the model, and have appeared as top results in previous analyses (like ORA and thresholded analysis). Many of the gene sets identified are closely related to these overall themes; for example, “DNA REPLICATION,” “DNA IR- DAMAGE AND CELLULAR RESPONSE” (repair), “G1 S TRANSITION” (cell cycle), “EUKARYOTIC TRANSLATION,” and “COLLAGEN FIBRIL ORGANIZATION” (extracellular matrix structure), among others. Among all of these themes and pathways, none were identified as being novel.
4. Interpretation
When comparing the results of the enrichment to the original paper, we see that there are few similarities. The paper identified several pathways as being enriched, but the first major difference is that the authors found that “all significantly enriched pathways were upregulated” (emphasis mine), whereas here, the majority of enriched pathways were found to be downregulated. The study placed significant focus on pathways and gene sets related to the immune system, as AD has been thought to be an autoimmune disease, and found many pathways (e.g., the T cell receptor signalling pathway) to be enriched. In my enrichment, immune-related sets do not dominate; in fact, immunity is not even present as a significant theme. Instead, the results tend to lean toward more generic pathways. For example, some of the most significantly enriched (and upregulated) sets were “electron transport atp” and “organic acid catabolic.”
However, there are at least some similarities with the original paper. For example, we see some processes related to DNA repair and replication that have been found to be enriched. Despite the other differences in results, this can still suggest that AD is directly or indirectly linked to these mechanisms.
Comparisons to the thresholded analysis performed in the previous report have already been discussed (the results somewhat agree), but we can revisit it anyway. Regarding the number of pathways/gene sets found by each method, we see that thresholded analysis finds more upregulated pathways and fewer downregulated pathways than enrichment analysis, but many of the specific sets can be found to be related to each other across analyses. In addition, the network structures reveal that many of those sets are related to each other, providing further insight into the expression profile of AD.
Overall, it seems that it is possible and perhaps even likely that I have made some small mistakes in my analyses, because as I perform more, the results become increasingly divergent from the results of the original paper. After cleaning and normalizing the dataset, results were fairly in line with the original study, but as the processes began to build up from each other, results began to differ. For example, after conducting the thresholded over-representation analysis, I could only conclude that the results were partially supported by the original study. Now after the non- thresholded analysis, even fewer results can be supported. It would probably be a good idea to revisit each of the previous steps and try to replicate the study’s results.
From the ORA report, we know that (Oka et al., 2015), (Panzer et al., 2014), and (Mansouri & Guttman-Yassky, 2015) all support the findings of the thresholded analysis (IL-19, TLR4, and the effects of dupilumab and cyclosporine, respectively) and the original paper, but since the enrichment analysis does not completely disagree with the study, we can still find additional sources to support some of the pathways/gene sets. For example, some sets were found to be related to viral DNA replication. A study by (Wollenberg et al., 2003) found that AD patients may be more vulnerable to specific types of viral infections, and gives a possible mechanism, related to DNA replication in the patient, as explanation. In addition, the major theme of DNA repair is supported by (Karaman & Aliagaoglu, 2006), which found that “increased chromosome instability [in relation to the DNA repair of AD patients] may plan an important role in the etiology of AD.” So despite my enrichment results not completely agreeing with (Möbus et al., 2021), the process did find support in other published articles for some other possibly related concepts.
5. DrugBank Post-Analysis
The final part of the analysis will be to run a post-analysis on the main enrichment network using DrugBank. We know from the original study (Möbus et al., 2021) that the drugs dupilumab and cyclosporine can be used to effectively treat AD, which is additionally supported by (Mansouri & Guttman-Yassky, 2015) and (Ariens et al., 2019), so it would be appropriate to try running a post-analysis on the primary enrichment map to determine if it can be verified here.
First, we will download the FDA-approved DrugBank dataset for human use (this GMT file is targeted because we already know that dupilumab and cyclosporine have been approved for use in treating AD). This can be done in a very similar fashion as to how the GSEA gene set was downloaded from the Bader Lab previously; the following snippet accomplishes exactly that. Alternatively, since the post-analysis will be run locally, it can also be downloaded directly from within Cytoscape by loading the signature gene set from the web.
We will begin with a targeted apporach, using only the known signatures of these two drugs. A copy of the GMT file was made, and all lines other than dupilumab and cyclosporine were removed. This was loaded as the signature set in Cytoscape, and the post-analysis was run with default parameters (Mann-Whitney Two-Sided test with cutoff 0.05). The result was that neither of the two drugs were able to pass. Dupilumab had a final p-value of 0.1832 and overlap of 1, and cyclosporine had a p-value of 0.8844 and overlap of 1. This suggests that either these drugs should not be significantly effective in treating AD, or there may be an issue with the enrichment map; the latter is more likely, because of the fact that the drugs have already been approved for use. Perhaps this result is not too surprising, considering the results of the enrichment analysis compared to the original paper (see the Interpretation section above for more details), but it may still be interesting to conduct an additional exploratory signature analysis to see what other drugs may have similar effects.
Running the post-analysis with default settings and the entire DrugBank GMT file (not just filtered to dupilumab and cyclosporine) yielded 68 results, which made the resulting map too cluttered. To reduce the number of results, the cutoff was reduced to 0.01, which yielded 13 results, a far more manageable amount.

Table 3. The list of 13 drugs that passed the Mann-Whitney test for cutoff 0.01.
Looking over this list of drugs, we see many “generic” compounds like NADH and zinc, which we can already guess probably do not help in the treatment of AD. Again, this is likely due to a poor enrichment map construction, where many nodes are able to achieve higher levels of overlap just because the most significantly enriched gene sets are not specific to AD. The following two figures show the signature drug set on top of the existing enrichment map, which may help to show which particular sets have connections to specific drugs.

Figure 6. The signature set overlayed onto the entire main enrichment map.

Figure 7. Nodes in the enrichment map that have no connections to any node in the signature set have been removed. The labels of the nodes in the signature set may be too small to read here, so it may be helpful to view the image separately.
6. References
Ariens, L. F. M., Gadkari, A., Van Os-Medendorp, H., Ayyagari, R., Terasawa, E., Kuznik, A., Chen, Z., Bego-Le Bagousse, G., Lu, Y., Rizova, E., Graham, N. M. H., Pirozzi, G., De Bruin-Weller, M., & Eckert, L. (2019). Dupilumab versus cyclosporine for the treatment of moderate-to-severe atopic dermatitis in adults: Indirect comparison using the eczema area and severity index.
Acta Derm Venereol,
99, 851–857.
https://doi.org/10.2340/00015555-3219
Davis, S., & Meltzer, P. (2007). GEOquery: A bridge between the gene expression omnibus (GEO) and BioConductor.
Bioinformatics,
23(14), 1846–1847.
https://doi.org/10.1093/bioinformatics/btm254
Durinck, S., Spellman, P. T., Birney, E., & Huber, W. (2009). Mapping identifiers for the integration of genomic datasets with the r/bioconductor package biomaRt.
Nat Protoc,
4(8), 1184–1191.
https://doi.org/10.1038/nprot.2009.97
Karaman, A., & Aliagaoglu, C. (2006). Frequency of sister chromatid exchanges in the lymphocytes of patients with atopic dermatitis.
J Dermatol,
33, 596–602.
https://doi.org/10.1111/j.1346-8138.2006.00144.x
Kucera, M. (2017).
BaderLab/AutoAnnotateApp.
https://github.com/BaderLab/AutoAnnotateApp
Mansouri, Y., & Guttman-Yassky, E. (2015). Immune pathways in atopic dermatitis, and definition of biomarkers through broad and targeted therapeutics.
J Clin Med,
4(5), 858–873.
https://doi.org/10.3390/jcm4050858
Merico, D., Isserlin, R., Stueker, O., Emili, A., & Bader, G. D. (2010). Enrichment map: A network-based method for gene-set enrichment visualization and interpretation.
PLoS One,
5(11), 13984.
https://doi.org/10.1371/journal.pone.001398
Möbus, L., Rodriguez, E., Harder, I., Stölzl, D., Boraczynski, N., Gerdes, S., Kleinheinz, A., Abraham, S., Heratizadeh, A., Handrick, C., Haufe, E., Werfel, T., Schmitt, J., Weidinger, S., & the TREATgermany study group. (2021). Atopic dermatitis displays stable and dynamic skin transcriptome signatures.
J Allergy Clin Immun,
147(1), 213–223.
https://doi.org/10.1016/j.jaci.2020.06.012
Mootha, V. K., Lindren, C. M., Eriksson, K.-F., Subramanian, A., Sihag, S., Lehar, J., Puigserver, P., Carlsson, E., Ridderstråle, M., Laurila, E., Houstis, N., Daly, M. J., Patterson, N., Mesirov, J. P., Golub, T. R., Tamayo, P., Spiegelman, B., Lander, E. S., Hirschhorn, J. N., … Groop, L. C. (2003). PGC-1α-responsive genes involved in oxidative phosphorylation are coordinately downregulated in human diabetes.
Nat Genet,
34, 267–273.
https://doi.org/10.1038/ng1180
Morgan, M. (2021).
BiocManager: Access the bioconductor project package repository.
https://CRAN.R-project.org/package=BiocManager
Morris, J. H., Apeltsin, L., Newman, A. M., Baumbach, J., Wittkop, T., Su, G., Bader, G. D., & Ferring, T. E. (2011). clusterMaker: A multi-algorithm clustering plugin for cytoscape.
BMC Bioinformatics,
12, 436.
https://doi.org/10.1186/1471-2105-12-436
Oesper, L., Merico, D., Isserlin, R., & Bader, G. D. (2011). WordCloud: A cytoscape plugin to create a visual semantic summary of networks.
Source Code Biol Med,
6, 7.
https://doi.org/10.1186/1751-0473-6-7
Oka, T., Sugaya, M., Takahashi, N., Nakajima, R., Otobe, S., Kabasawa, M., Suga, H., Miyagaki, T., Asano, Y., & Sato, S. (2015). Increased interleukin-19 expression in cutaneous t-cell lymphoma and atopic dermatitis.
Acta Derm Venereol,
97(10), 1172–1177.
https://doi.org/10.2340/00015555-2723
Panzer, R., Blobel, C., Fölster-Holst, R., & Proksch, E. (2014). TLR2 and TLR4 expression in atopic dermatitis, contact dermatitis and psoriasis.
Exp Dermatol,
23(5), 364–366.
https://doi.org/10.1111/exd.12383
Robinson, M. D., McCarthy, D. J., & Smyth, G. K. (2010). edgeR: A bioconductor package for differential expression analysis of digital gene expression data.
Bioinformatics,
26(1), 139–140.
https://doi.org/10.1093/bioinformatics/btp616
Shannon, P., Markiel, A., Ozier, O., Baliga, N. S., Wang, J. T., Ramage, D., Amin, N., Schwikowski, B., & Ideker, T. (2003). Cytoscape: A software environment for integrated models of biomolecular interaction networks.
Genome Res,
13(11), 2498–2504.
https://doi.org/10.1101/gr.1239303
Subramanian, A., Tamayo, P., Mootha, V. K., Mukherjee, S., Ebert, B. L., Gillette, M. A., Paulovich, A., Pomeroy, S. L., Golub, T. R., Lander, E. S., & Mesirov, J. P. (2005). Gene set enrichment analysis: A knowledge-based approach for interpreting genome-wide expression profiles.
P Natl Acad Sci-Biol,
102(43), 15545–15550.
https://doi.org/10.1073/pnas.0506580102
Wollenberg, A., Wetzel, S., Burgdorf, W. H. C., & Haas, J. (2003). Viral infections in atopic dermatitis: Pathogenic aspects and clinical management.
J Allergy Clin Immunol,
112(4), 667–674.
https://doi.org/10.1067/mai.2003.1775
Xie, Y. (2021).
Knitr: A general-purpose package for dynamic report generation in r.
https://yihui.org/knitr
LS0tCnRpdGxlOiAiQkNCNDIwIEEzIC0gRGF0YXNldCBQYXRod2F5IGFuZCBOZXR3b3JrIEFuYWx5c2lzIgphdXRob3I6ICJZaWppYSBDaGVuIgpkYXRlOiAiMjAyMi0wNC0wNiIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKYmlibGlvZ3JhcGh5OiBBM19jaXRhdGlvbnMuYmliCmNzbDogYXBhLmNzbApub2NpdGU6ICJAKiIKLS0tCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGluY2x1ZGUgPSBGQUxTRX0KIyBTZXR1cDogc2V2ZXJhbCBSIHBhY2thZ2VzIGFyZSByZXF1aXJlZCB0byBydW4gdGhpcyBub3RlYm9vay4gVGhleSBjYW4gYmUgaW5zdGFsbGVkIGJ5IHJ1bm5pbmcgdGhpcyBzbmlwcGV0ICh0aGUgY29kZQojIHdpbGwgbm90IGJlIGluY2x1ZGVkIGluIHRoZSBmaW5hbCByZXBvcnQpLgoKaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJCaW9jTWFuYWdlciIsIHF1aWV0bHkgPSBUUlVFKSkgewogIGluc3RhbGwucGFja2FnZXMoIkJpb2NNYW5hZ2VyIikKfQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImtuaXRyIiwgcXVpZXRseSA9IFRSVUUpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQp9CmlmICghcmVxdWlyZU5hbWVzcGFjZSgiUkN1cmwiLCBxdWlldGx5ID0gVFJVRSkpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpCn0KYGBgCgojIyAxLiBJbnRyb2R1Y3Rpb24KClRoaXMgbm90ZWJvb2sgY29udGFpbnMgYSBwYXRod2F5IGFuZCBuZXR3b3JrIGFuYWx5c2lzIGZvciB0aGUgc2V0IG9mIHJhbmtlZCBnZW5lcyBvYnRhaW5lZCBmcm9tIHRoZSBHRU8gZGF0YXNldApbR1NFMTU3MTk0XShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L2dlby9xdWVyeS9hY2MuY2dpP2FjYz1HU0UxNTcxOTQpLCBhc3NvY2lhdGVkIHdpdGggdGhlIHB1YmxpY2F0aW9uICJBdG9waWMKZGVybWF0aXRpcyBkaXNwbGF5cyBzdGFibGUgYW5kIGR5bmFtaWMgc2tpbiB0cmFuc2NyaXB0b21lIHNpZ25hdHVyZXMiIFtAbW9idXNdLiBUaGUgZ29hbCBvZiB0aGUgc3R1ZHkgd2FzIHRvIHVuZGVyc3RhbmQKdGhlIGVmZmVjdHMgb2YgdGhlIGRydWdzIGR1cGlsdW1hYiBhbmQgY3ljbG9zcG9yaW5lIG9uIGF0b3BpYyBkZXJtYXRpdGlzIChBRCkgYnkgY29uZHVjdGluZyBhIGdlbmUgZXhwcmVzc2lvbiBzdHVkeQp1c2luZyBtUk5BLXNlcSBkYXRhIHRha2VuIGZyb20gYmlvcHNpZXMgb2YgaHVtYW4gcGF0aWVudHMuCgpUaGUgcmF3IGNvdW50IG1hdHJpeCB3YXMgZmlyc3QgZG93bmxvYWRlZCB2aWEgR0VPcXVlcnkgW0BnZW9xdWVyeV0sIGFuZCB0aGUgZGF0YSB3YXMgY2xlYW5lZCB0byBjb25maXJtIHRoYXQgbm8KZHVwbGljYXRlcyB3ZXJlIHByZXNlbnQuIE5leHQsIHRoZSBkYXRhIHdhcyB0aGVuIGZpbHRlcmVkIGJ5IGdlbmUsIHJlbW92aW5nIHRob3NlIHdpdGhvdXQgYXQgbGVhc3Qgb25lIHJlYWQgcGVyIG1pbGxpb24KaW4gZWFjaCBzYW1wbGUsIGFuZCBhbHNvIGJ5IHBhdGllbnQsIHJlbW92aW5nIHRob3NlIHdpdGggaW5jb21wbGV0ZSBkYXRhLiBFbnNlbWJsIElEcyB3ZXJlIG1hcHBlZCB0byBIVUdPIGdlbmUgc3ltYm9scwp1c2luZyBiaW9tYVJ0IFtAYmlvbWFydF0sIGFuZCBnZW5lcyB0aGF0IHdlcmUgdW5hYmxlIHRvIGJlIGNvbnZlcnRlZCAoZS5nLiwgbm92ZWwgZ2VuZXMpIHdlcmUgcmVtb3ZlZC4gVG8gbm9ybWFsaXplIHRoZQpkYXRhLCB0cmltbWVkIG1lYW4gb2YgbS12YWx1ZXMgd2FzIHVzZWQgW0BlZGdlcl0sIHNpbmNlIHRoZSBhc3N1bXB0aW9uIHdhcyB0aGF0IG1vc3QgZ2VuZXMgd2VyZSBub3QgZGlmZmVyZW50aWFsbHkKZXhwcmVzc2VkLiBTZWUgW3RoaXMgcmVwb3J0XShodHRwczovL2dpdGh1Yi5jb20vYmNiNDIwLTIwMjIvWWlqaWFfQ2hlbi9ibG9iL21haW4vQTEubmIuaHRtbCkgZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUKZGF0YXNldCwgaXRzIGNsZWFuaW5nLCBhbmQgaXRzIG5vcm1hbGl6YXRpb24uCgpUaGUgb2J0YWluZWQgbGlzdCBvZiBnZW5lcyB3YXMgbmV4dCB1c2VkIHRvIHBlcmZvcm0gYSBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIGFuYWx5c2lzIHVzaW5nIGEgcXVhc2ktbGlrZWxpaG9vZAptb2RlbCBbQGVkZ2VyXSwgYW5kIHRoZSByZXN1bHRpbmcgcC12YWx1ZXMgZm9yIGVhY2ggZ2VuZSB3ZXJlIGNvbnZlcnRlZCB0byByYW5rICh1c2luZyB0aGUgZm9ybXVsYQokXHRleHR7LX1caHNwYWNley0wLjZtbX1cbG9nX3sxMH0ocFx0ZXh0ey19dmFsdWUpIFx0aW1lcyBcdGV4dHtzaWdufShsb2dGQykkKS4gVGhlIHJlc3VsdGluZyBzZXQgb2YgcmFua2VkIGdlbmVzIHdhcwp0aGVuIHNvcnRlZCBieSBkZXNjZW5kaW5nIHJhbmsgYW5kIHdyaXR0ZW4gdG8gdGhlIGZpbGUgcmFua2VkR2VuZUxpc3Qucm5rLCB3aGljaCB3aWxsIGJlIHRoZSBzdGFydGluZyBwb2ludCBmb3IgR1NFQS4KU2VlIFt0aGlzIHJlcG9ydF0oaHR0cHM6Ly9naXRodWIuY29tL2JjYjQyMC0yMDIyL1lpamlhX0NoZW4vYmxvYi9tYWluL0EyX1lpamlhQ2hlbi5uYi5odG1sKSBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZQpnZW5lIGV4cHJlc3Npb24gYW5hbHlzaXMgKGFuZCBhZGRpdGlvbmFsIG92ZXItcmVwcmVzZW50YXRpb24gYW5hbHlzaXMpLgoKVGhlIGNvcnJlc3BvbmRpbmcgam91cm5hbCBlbnRyeSBmb3IgdGhpcyBub3RlYm9vayBjYW4gYmUgZm91bmQKW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9iY2I0MjAtMjAyMi9ZaWppYV9DaGVuL3dpa2kvMTAuLUFzc2lnbm1lbnQtMy0lRTIlODAlOTAtRGF0YXNldC1wYXRod2F5LWFuZC1uZXR3b3JrLWFuYWx5c2lzKS4KV2UgY2FuIGJlZ2luIGJ5IHRha2luZyBhIGxvb2sgYXQgdGhlIHRvcCBhbmQgYm90dG9tIG9mIHRoZSBsaXN0IG9mIHJhbmtlZCBnZW5lcyB0byBnZXQgYW4gaWRlYSBvZiB3aGF0IHRoZSB0YWJsZSBsb29rcwpsaWtlOgoKYGBgIHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KIyBNYWtlIHN1cmUgdGhlIHJhbmsgZmlsZSBleGlzdHMKcmFua0ZpbGUgPC0gZmlsZS5wYXRoKGdldHdkKCksICJyYW5rZWRHZW5lTGlzdC5ybmsiKQppZiAoIWZpbGUuZXhpc3RzKHJhbmtGaWxlKSkgewogIHN0b3AoIlJhbmsgZmlsZSBub3QgZm91bmQiKQp9CgpyYW5rTGlzdCA8LSByZWFkLnRhYmxlKGZpbGUgPSByYW5rRmlsZSwKICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXHQiLAogICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIGNoZWNrLm5hbWVzID0gRkFMU0UpCmtuaXRyOjprYWJsZShyYW5rTGlzdFsxOjUsIF0sIHR5cGUgPSAiaHRtbCIpCmBgYAoKPGNlbnRlcj4KVGFibGUgMS4gVGhlIGZpcnN0IGZpdmUgZ2VuZXMgaW4gdGhlIHJhbmtlZCBnZW5lIGxpc3QuCjwvY2VudGVyPgoKYGBgIHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0Kc3RvcElkeCA8LSBucm93KHJhbmtMaXN0KQpzdGFydElkeCA8LSBzdG9wSWR4IC0gNQprbml0cjo6a2FibGUocmFua0xpc3Rbc3RhcnRJZHg6c3RvcElkeCwgXSwgdHlwZSA9ICJodG1sIikKYGBgCgo8Y2VudGVyPgpUYWJsZSAyLiBUaGUgbGFzdCBmaXZlIGdlbmVzIGluIHRoZSByYW5rZWQgZ2VuZSBsaXN0Lgo8L2NlbnRlcj4KCiMjIDIuIE5vbi1UaHJlc2hvbGRlZCBHZW5lIFNldCBFbnJpY2htZW50IEFuYWx5c2lzIChHU0VBKQoKVGhlIEdTRUEgcHJlLXJhbmtlZCBtZXRob2Qgd2lsbCBiZSB1c2VkIGZvciBhbmFseXNpcyBbQGdzZWExXSBbQGdzZWEyXSAodmVyc2lvbiA0LjIuMywgcnVuIGxvY2FsbHksIHdpdGggdGhlIHJlc3VsdHMKcHJlc2VudGVkIGhlcmUpLgoKRmlyc3QsIHdlIHdpbGwgbmVlZCBhIGdlbmUgc2V0IGZpbGUgZm9yIHRoZSBhbmFseXNpcy4gRm9yIHRoaXMsIHdlIGNhbiBkb3dubG9hZCBvbmUgcHJvdmlkZWQgYnkgdGhlIEJhZGVyIExhYiBbQGJhZGVyXQooc2VlIGh0dHA6Ly9kb3dubG9hZC5iYWRlcmxhYi5vcmcvRU1fR2VuZXNldHMpLiBUaGVzZSBzZXRzIGNvbnRhaW4gbWFueSBzb3VyY2VzIChzZWUgdGhlIGxpc3QKW2hlcmVdKGh0dHA6Ly9iYWRlcmxhYi5vcmcvR2VuZVNldHMpKSBhbmQgYXJlIHVwZGF0ZWQgcmVndWxhcmx5IChtb250aGx5KSwgc28gYXJlIGlkZWFsIGZvciB0aGlzIHRhc2suIEluIHBhcnRpY3VsYXIsCndlIHdpbGwgY2hvb3NlIG9uZSBmb3IgaHVtYW4gZ2VuZXMsIGNvbnRhaW5zIGFsbCBHTzpCUCBwYXRod2F5cyAoc2luY2Ugd2UgYXJlIG1vc3RseSBmb2N1c2VkIG9uIHBhdGh3YXlzKSwgYW5kIGV4Y2x1ZGVzCmluZmVycmVkIGVsZWN0cm9uaWMgYW5ub3RhdGlvbnMgKHNpbmNlIHdlIHdhbnQgb3VyIGFuYWx5c2lzIHRvIGJlIG1vcmUgc3BlY2lmaWMgb3IgY3VyYXRlZCkuIEFzIG9mIHRoZSB0aW1lIG9mIHdyaXRpbmcsCnRoZSBtb3N0IHVwZGF0ZWQgdmVyc2lvbiBvZiB0aGUgZmlsZSB0aGF0IHNhdGlzZmllcyB0aGVzZSBjcml0ZXJpYSBpcyBmcm9tIEFwcmlsIDEsIDIwMjIsIHNvIHRoaXMgd2lsbCBiZSB0aGUgdmVyc2lvbgpkb3dubG9hZGVkIGFuZCB1c2VkIGhlcmUgKEh1bWFuX0dPQlBfQWxsUGF0aHdheXNfbm9fR09faWVhX0FwcmlsXzAxXzIwMjJfc3ltYm9sLmdtdCkuCgpgYGAge3IsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCByZXN1bHRzID0gImhpZGUifQojIEdldCBhIGxpc3Qgb2YgYWxsIHRoZSBhdmFpbGFibGUgZ2VuZSBzZXQgZmlsZXMKZ3NVcmwgPC0gImh0dHA6Ly9kb3dubG9hZC5iYWRlcmxhYi5vcmcvRU1fR2VuZXNldHMvY3VycmVudF9yZWxlYXNlL0h1bWFuL3N5bWJvbC8iCmZpbGVzIDwtIFJDdXJsOjpnZXRVUkwoZ3NVcmwpCmNvbm4gPC0gdGV4dENvbm5lY3Rpb24oZmlsZXMpCmNvbnRlbnRzIDwtIHJlYWRMaW5lcyhjb25uKQpjbG9zZShjb25uKQoKIyBGaW5kIHRoZSBHTVQgZmlsZSB3aXRoIGFsbCBHTzpCUCBwYXRod2F5cyBhbmQgbm8gZWxlY3Ryb25pYyBhbm5vdGF0aW9ucwpyZWdleCA8LSBncmVnZXhwcigiKD88PTxhIGhyZWY9XCIpKC4qLkdPQlBfQWxsUGF0aHdheXNfbm9fR09faWVhLiouKSguZ210KSg/PVwiPikiLCBjb250ZW50cywgcGVybCA9IFRSVUUpCmdtdCA8LSB1bmxpc3QocmVnbWF0Y2hlcyhjb250ZW50cywgcmVnZXgpKQoKIyBEb3dubG9hZCB0aGUgZmlsZSBpZiBpdCBoYXMgbm90IGJlZW4gZG93bmxvYWRlZCBhbHJlYWR5CiMgV2FybmluZzogaXQgbWF5IGRvd25sb2FkIGEgbW9yZSB1cC10by1kYXRlIGdlbmUgc2V0OyBpZiBkb2luZyBjb21wYXJpc29ucyBvciB0cnlpbmcgdG8gcmVwcm9kdWNlIHJlc3VsdHMsIG1ha2Ugc3VyZQojIHRvIGNoZWNrIHRoZSB2ZXJzaW9uIG51bWJlcgpnbXRGaWxlIDwtIGZpbGUucGF0aChnZXR3ZCgpLCBnbXQpCmlmICghZmlsZS5leGlzdHMoZ210RmlsZSkpIHsKICBkb3dubG9hZC5maWxlKHBhc3RlKGdzVXJsLCBnbXQsIHNlcCA9ICIiKSwgZGVzdGZpbGUgPSBnbXRGaWxlKQp9CmBgYAoKVGhlIEdTRUEgc2V0dGluZ3MgdXNlZCB3ZXJlIGFzIGZvbGxvd3M6ICAKTnVtYmVyIG9mIHBlcm11dGF0aW9uczogMTAwMCAgCkNvbGxhcHNlL1JlbWFwIHRvIGdlbmUgc3ltYm9sczogTm9fQ29sbGFwc2UgIApFbnJpY2htZW50IHN0YXRpc3RpYzogd2VpZ2h0ZWQgIApNYXggc2l6ZTogMjAwICAKTWluIHNpemU6IDE1CgpTb21lIGV4cGxhbmF0aW9ucyBmb3IgdXNpbmcgdGhlc2UgcGFyYW1ldGVycyBjYW4gYmUgZm91bmQKW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9iY2I0MjAtMjAyMi9ZaWppYV9DaGVuL3dpa2kvMDkuLUdTRUEpLgoKIyMjIFN1bW1hcnkgb2YgUmVzdWx0cwoKVGhlIGRhdGFzZXQgaGFzIDE3LDc0NyBnZW5lcywgYWxsIG9mIHdoaWNoIHdlcmUgdXNlZCBpbiB0aGUgYW5hbHlzaXMuIFRoZSBnZW5lIHNldCBoYWQgMTgsNTM2IGdlbmVzLCBidXQgYWZ0ZXIgYXBwbHlpbmcKdGhlIG1pbmltdW0gYW5kIG1heGltdW0gc2l6ZSBmaWx0ZXJzLCB0aGUgbnVtYmVyIHdhcyByZWR1Y2VkIHRvIDUsNTkxIChhIHJlZHVjdGlvbiBvZiAxMiw5NDUgc2V0cykuCgpGb3IgdGhlIHVwcmVndWxhdGVkIHNldHM6CgoqIDEsMTg2IGdlbmUgc2V0cyB3ZXJlIGZvdW5kIHRvIGJlIHVwcmVndWxhdGVkIChvZiB0aGUgNSw1OTEpCiogMzUwIHNldHMgd2VyZSBzaWduaWZpY2FudCBhdCBGRFIgPCAwLjI1CiogMzM4IHNldHMgd2VyZSBzaWduaWZpY2FudGx5IGVucmljaGVkIHdpdGggcC12YWx1ZSA8IDAuMDUKKiAxOTEgc2V0cyB3ZXJlIHNpZ25pZmljYW50bHkgZW5yaWNoZWQgd2l0aCBwLXZhbHVlIDwgMC4wMQoqIFRoZSB0b3Agc2V0IHdhcyAiUEVQVElERSBDSEFJTiBFTE9OR0FUSU9OJVJFQUNUT01FIERBVEFCQVNFIElEIFJFTEVBU0UgNzklMTU2OTAyIiB3aXRoIHRoZSBmb2xsb3dpbmcgZGV0YWlsczoKICAqIEVucmljaG1lbnQgc2NvcmUgb2YgMC43NTE0NTgxNwogICogTm9ybWFsaXplZCBlbnJpY2htZW50IHNjb3JlIG9mIDIuNzU1Njg4NwogICogcC12YWx1ZSBvZiAwLjAKICAqIEZEUiBvZiAwLjAKICAqIExlYWRpbmcgZWRnZSBzZXQgaGFzIHNpemUgNzEKICAqIFRvcCBnZW5lIGlzIFJQUzE4CiAgCkZvciB0aGUgZG93bnJlZ3VsYXRlZCBzZXRzOgoKKiA0LDQwNSBnZW5lIHNldHMgd2VyZSBmb3VuZCB0byBiZSBkb3ducmVndWxhdGVkCiogMiwwNTMgc2V0cyB3ZXJlIHNpZ25pZmljYW50IGF0IEZEUiA8IDAuMjUKKiAxLDUwNiBzZXRzIHdlcmUgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCB3aXRoIHAtdmFsdWUgPCAwLjA1CiogODI0IHNldHMgd2VyZSBzaWduaWZpY2FudGx5IGVucmljaGVkIHdpdGggcC12YWx1ZSA8IDAuMDEKKiBUaGUgdG9wIHNldCB3YXMgIkhBTExNQVJLX0UyRl9UQVJHRVRTJU1TSUdEQl9DMiVIQUxMTUFSS19FMkZfVEFSR0VUUyIgd2l0aCB0aGUgZm9sbG93aW5nIGRldGFpbHM6CiAgKiBFbnJpY2htZW50IHNjb3JlIG9mIC0wLjY2NDY4NTgKICAqIE5vcm1hbGl6ZWQgZW5yaWNobWVudCBzY29yZSBvZiAtMi4xODIwMzc4CiAgKiBwLXZhbHVlIG9mIDAuMAogICogRkRSIG9mIDAuMAogICogTGVhZGluZyBlZGdlIHNldCBoYXMgc2l6ZSA5OAogICogVG9wIGdlbmUgaXMgRVNQTDEKICAKIyMjIENvbXBhcmlzb24gdG8gVGhyZXNob2xkZWQgQW5hbHlzaXMKClRoZSBpZGVhIG9mIGNvbXBhcmluZyB0aGVzZSByZXN1bHRzIHRvIHRoZSB0aHJlc2hvbGRlZCBhbmFseXNpcyAoVEEpIChzZWUKW3RoaXMgcmVwb3J0XShodHRwczovL2dpdGh1Yi5jb20vYmNiNDIwLTIwMjIvWWlqaWFfQ2hlbi9ibG9iL21haW4vQTJfWWlqaWFDaGVuLm5iLmh0bWwpKSBpcyBub3QgdmVyeSBzdHJhaWdodGZvd2FyZCwKYmVjYXVzZSB3aGVyZWFzIFRBIG9ubHkgdXNlZCBnZW5lcyB0aGF0IHdlcmUgZm91bmQgdG8gYmUgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgKGFuZCBpdCB3YXMgYWxzbwpwb3NzaWJsZSB0byBydW4gdGhlIGFuYWx5c2VzIHNlcGFyYXRlbHkgZm9yIHVwLSBhbmQgZG93bi1yZWd1bGF0ZWQgZ2VuZXMpLCB0aGlzIG5vbi10aHJlc2hvbGRlZCBhbmFseXNpcyAoTlRBKSB1c2VkCmV2ZXJ5IGdlbmUsIGFsbCBhdCBvbmNlLCByZWdhcmRsZXNzIG9mIHRoZSBsZXZlbCBvZiBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbi4gSG93ZXZlciwgd2UgY2FuIHN0aWxsIHRyeSB0byBjb21wYXJlIHRoZQpyZXN1bHRzLCBhcyBpdCBtYXkgcHJvdmlkZSBzb21lIGZ1cnRoZXIgaW5zaWdodCBpbnRvIHRoZSBvYnNlcnZlZCBwYXRod2F5cy4KCkxvb2tpbmcgYXQgdGhlIHVwcmVndWxhdGVkIGdlbmVzLCB3ZSBzZWUgdGhhdCBUQSBmb3VuZCA1LDAyNywgMSwwMDcsIGFuZCA0NDUgcGF0aHdheXMsIGJ5IEdPOkJQLCBSRUFDLCBhbmQKV2lraVBhdGh3YXlzLCByZXNwZWN0aXZlbHksIHdoZXJlYXMgTlRBIG9ubHkgZm91bmQgMSwxODYgc2V0cy4gTW9yZSBzcGVjaWZpY2FsbHksIFRBJ3MgbW9zdCBzaWduaWZpY2FudCBmb3VuZCBwYXRod2F5cwp3ZXJlIHJlbGF0ZWQgdG8gbWV0YWJvbGljIHByb2Nlc3NlcyAoZS5nLiwgImxvbmctY2hhaW4gZmF0dHkgYWNpZCBtZXRhYm9saWMgcHJvY2VzcyIgYW5kICJ1bnNhdHVyYXRlZCBmYXR0eSBhY2lkCm1ldGFib2xpYyBwcm9jZXNzIiksIHdoZXJlYXMgTlRBJ3MgbW9zdCBzaWduaWZpY2FudCBzZXRzIHdlcmUgc29tZXdoYXQgbW9yZSByZWxhdGVkIHRvIHRyYW5zbGF0aW9uIChlLmcuLCAiVklSQUwgTVJOQQpUUkFOU0xBVElPTiIgYW5kICJFVUtBUllPVElDIFRSQU5TTEFUSU9OIEVMT05HQVRJT04iKSwgd2l0aCBtZXRhYm9saWMgcHJvY2Vzc2VzIHNsaWdodGx5IGZ1cnRoZXIgZG93biB0aGUgbGlzdC4gVGhpcwpkaWZmZXJlbmNlIGNvdWxkIHBvc3NpYmx5IGJlIGV4cGxhaW5lZCBieSB0aGUgaXNzdWUgbm90ZWQgcHJldmlvdXNseTsgVEEgb25seSB1c2VkIHNpZ25pZmljYW50bHkgdXByZWd1bGF0ZWQgZ2VuZXMgZm9yCnRoaXMgcGFydCBvZiB0aGUgYW5hbHlzaXMuCgpMb29raW5nIGF0IHRoZSBkb3ducmVndWxhdGVkIGdlbmVzLCB3ZSBzZWUgdGhhdCBUQSBmb3VuZCAyMzAsIDcyLCBhbmQgNTIgcGF0aHdheXMsIGJ5IEdPOkJQLCBSRUFDLCBhbmQgV1AsCnJlc3BlY3RpdmVseSwgd2hlcmVhcyBOVEEgZm91bmQgNCw0MDUgc2V0cy4gTW9yZSBzcGVjaWZpY2FsbHksIFRBJ3MgbW9zdCBzaWduaWZpY2FudCBmb3VuZCBwYXRod2F5cyB3ZXJlIHJlbGF0ZWQgdG8gRE5BCnJlcGxpY2F0aW9uIChlLmcuLCAiY2VsbCBjeWNsZSBETkEgcmVwbGljYXRpb24iIGFuZCAiRE5BLWRlcGVuZGVudCBETkEgcmVwbGljYXRpb24iKSwgYW5kIE5UQSdzIG1vc3Qgc2lnbmlmaWNhbnQgc2V0cwp3ZXJlIHNvbWV3aGF0IHNpbWlsYXIgKGUuZy4sICJETkEgSVItREFNQU5HRSBBTkQgQ0VMTFVMQVIgUkVTUE9OU0UiIGFuZCAiRE5BLVRFTVBMQVRFRCBETkEgUkVQTElDQVRJT04iKS4gT3ZlcmFsbCwgaXQKaXMgcG9zc2libGUgdG8gc2F5IHRoYXQgdGhlIGNvbXBhcmVkIHJlc3VsdHMgYXJlIHF1aXRlIHNpbWlsYXIsIGFuZCB0byBhIGRlZ3JlZSwgYWdyZWUgd2l0aCBlYWNoIG90aGVyLgoKIyMgMy4gVmlzdWFsaXphdGlvbiBvZiBHZW5lIFNldCBFbnJpY2htZW50IEFuYWx5c2lzIChDeXRvc2NhcGUpCgpUbyB2aXN1YWxpemUgdGhpcyBkYXRhIGFzIGEgbmV0d29yaywgQ3l0b3NjYXBlIFtAY3l0b3NjYXBlXSB3aWxsIGJlIHVzZWQgKHZlcnNpb24gMy45LjEsIHJ1biBsb2NhbGx5KSB3aXRoIHRoZQpFbnJpY2htZW50TWFwIFtAYmFkZXJdIHBpcGVsaW5lIChDeXRvc2NhcGUgYXBwIHZlcnNpb24gMy4zLjMpLiBPdGhlciBpbmNsdWRlZCBhcHBzIGFyZSBjbHVzdGVyTWFrZXIgMiBbQGNsdXN0ZXJtYWtlcl0KdmVyc2lvbiAyLjIsIFdvcmRDbG91ZGQgW0B3b3JkY2xvdWRdIHZlcnNpb24gMy4xLjQsIGFuZCBBdXRvQW5ub3RhdGUgW0BhdXRvYW5ub3RhdGVdIHZlcnNpb24gMS4zLjUsIGFsbCBkb3dubG9hZGVkIGZyb20KdGhlIEN5dG9zY2FwZSBBcHAgU3RvcmUgKHZpYSB0aGUgQ3l0b3NjYXBlIEFwcCBNYW5hZ2VyKS4KClRoZSBHU0VBIG91dHB1dCBkaXJlY3Rvcnkgd2FzIGxvYWRlZCBpbnRvIEVucmljaG1lbnRNYXAgd2l0aCB0aGUgZm9sbG93aW5nIHRocmVzaG9sZHMgKHdoaWNoIHdlcmUgcmVjb21tZW5kZWQgYnkgdGhlCkVucmljaG1lbnRNYXAgZG9jdW1lbnRhdGlvbiBbaGVyZV0oaHR0cHM6Ly9lbnJpY2htZW50bWFwLnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC9QYXJhbWV0ZXJzLmh0bWwjKSk6CgoqIEZEUiBjdXRvZmY6IDAuMDUKKiBwLXZhbHVlIGN1dG9mZjogMC4wMDEKKiBFZGdlIG1ldHJpYzogSmFjY2FyZCtPdmVybGFwIENvbWJpbmVkCiogRWRnZSBjdXRvZmY6IDAuNQoKVGhpcyBwcm9kdWNlZCB0aGUgZm9sbG93aW5nIHJhdyBpbWFnZSAobm8gbWFudWFsIGFkanVzdG1lbnRzIG9yIGxlZ2VuZHMsIGhpZGRlbiBsYWJlbHMpOgoKIVtdKGZpZ3VyZXMvZW1faW5pdGlhbC5wbmcpCgpGaWd1cmUgMS4gVGhlIGluaXRpYWwgZW5yaWNobWVudCBtYXAuIFRoZXJlIGFyZSA0NTcgbm9kZXMgYW5kIDEsMTYwIGVkZ2VzLgoKIyMjIEFubm90YXRpb24KClRoZSBuZXh0IHN0ZXAgaXMgdG8gYW5ub3RhdGUgdGhlIG5ldHdvcmsgd2l0aCBjbHVzdGVycy4gQXV0b0Fubm90YXRlIFtAYXV0b2Fubm90YXRlXSB3aXRoIGRlZmF1bHQgcGFyYW1ldGVycyAocGx1cyB0aGUKcHJldmVudGlvbiBvZiBjbHVzdGVyIG92ZXJsYXApIHdhcyB1c2VkIHRvIGFubm90YXRlIHRoZSBlbnRpcmUgbmV0d29yay4gU29tZSBvZiB0aGUga2V5IHBhcmFtZXRlcnMgYXJlIGFzIGZvbGxvd3M6CgoqIENsdXN0ZXIgb3B0aW9uczogdXNlIHRoZSBjbHVzdGVyTWFrZXIgYXBwIHRvIGRlZmluZSBjbHVzdGVycwoqIENsdXN0ZXIgYWxnb3JpdGhtOiBNQ0wgQ2x1c3RlcgoqIExhYmVsIG9wdGlvbnM6IHVzZSBnZW5lIGRlc2NyaXB0aW9ucyBhcyB0aGUgbGFiZWwgY29sdW1uCiogTGFiZWwgYWxnb3JpdGhtOiBXb3JkQ2xvdWQgKGFkamFjZW50IHdvcmRzKQogICogTWF4IHdvcmRzIHBlciBsYWJlbDogMwogICogTWluaW11bSB3b3JkIG9jY3VycmVuY2U6IDEKICAqIEFkamFjZW50IHdvcmQgYm9udXM6IDgKICAKVGhpcyBwcm9kdWNlZCB0aGUgZm9sbG93aW5nIGltYWdlOgoKIVtdKGZpZ3VyZXMvZW1fYW5ub3RhdGVkLnBuZykKCkZpZ3VyZSAyLiBUaGUgYXV0b21hdGljYWxseSBhbm5vdGF0ZWQgZW5yaWNobWVudCBtYXAuCgpXZSBub3RpY2UgdGhhdCB0aGUgbWFwcyBzbyBmYXIgYXJlIG1pc3NpbmcgbGVnZW5kczsgaXQgaXMgbm90IGltbWVkaWF0ZWx5IGNsZWFyIHdoaWNoIGNvbG91cnMgY29ycmVzcG9uZCB0byB3aGljaApkaXJlY3Rpb25zIG9mIHJlZ3VsYXRpb24uIFdlIGNhbiBoYXZlIHRoZSBlbnJpY2htZW50IG1hcCBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlIG9uZSwgd2hpY2ggbG9va3MgbGlrZSB0aGUgZm9sbG93aW5nOgoKPGNlbnRlcj4KIVtdKGZpZ3VyZXMvZW1fbGVnZW5kLnBuZyl7d2lkdGg9NTAlfQo8L2NlbnRlcj4KCkZpZ3VyZSAzLiBUaGUgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgbGVnZW5kLiBSZWQgaXMgZm9yIHVwcmVndWxhdGlvbiB3aGlsZSBibHVlIGlzIGZvciBkb3ducmVndWxhdGlvbi4KCldlIGNhbiB0aGVuIGNvbWJpbmUgdGhlIGFubm90YXRlZCBtYXAgd2l0aCB0aGUgbGVnZW5kIChhbmQgYWRkIGEgdGl0bGUpIHRvIGNyZWF0ZSBhICJwdWJsaWNhdGlvbi1yZWFkeSIgZmlndXJlOgoKIVtdKGZpZ3VyZXMvZW1fcHViLnBuZykKCkZpZ3VyZSA0LiBUaGUgY29tcGxldGUgZW5yaWNobWVudCBtYXAgZm9yIHRoZSBhbmFseXNpcywgd2l0aCBhbm5vdGF0ZWQgY2x1c3RlcnMsIGxlZ2VuZCwgYW5kIHRpdGxlIGFkZGVkLgoKVGhlIG1hcCBoYXMgcXVpdGUgYSBmZXcgc2lnbmlmaWNhbnQgZ2VuZSBzZXRzLCBtYWtpbmcgdGhlIHRleHQgaGFyZCB0byByZWFkIChiZWNhdXNlIHRoZXJlIGFyZSBzbyBtYW55IGNsdXN0ZXJzKSwgc28gaXQKbWF5IGJlIGhlbHBmdWwgdG8gb3BlbiB0aGUgaW1hZ2Ugc2VwYXJhdGVseSAocGVyaGFwcyBpbiBhIG5ldyB0YWIpIHdoZW4gbG9va2luZyBmb3Igc3BlY2lmaWMgc2V0cyBvciBqdXN0IGxvb2tpbmcgYXQKdGhlIGZpbmVyIGRldGFpbHMuCgpBbm90aGVyIHdheSB0byBsb29rIGF0IHRoZSBuZXR3b3JrIGlzIHRvIGNvbGxhcHNlIGFsbCBvZiB0aGUgY2x1c3RlcnMgdG8gbWFrZSBhIHRoZW1lIG5ldHdvcmsuIFRoaXMgbWF5IGhlbHAgaW4KaWRlbnRpZnlpbmcgdGhlIG1ham9yIHRoZW1lcyBwcmVzZW50LCB3aGljaCBjYW4gZnVydGhlciBzb2xpZGlmeSB0aGUgdW5kZXJzdGFuZGluZyBvZiByZWxldmFudCBwYXRod2F5cywgb3IgZXZlbiB0bwpwb3NzaWJseSBmaW5kIG5vdmVsIG9uZXMuCgohW10oZmlndXJlcy9lbV9jb2xsYXBzZWQucG5nKQoKRmlndXJlIDUuIFRoZSB0aGVtZSBuZXR3b3JrIGdlbmVyYXRlZCBieSBjb2xsYXBzaW5nIHRoZSBlbnJpY2htZW50IG1hcC4KCkFmdGVyIGNvbGxhcHNpbmcgdGhlIGNsdXN0ZXJzIGluIHRoZSBlbnJpY2htZW50IG1hcCwgd2UgY2FuIHNlZSBzZXZlcmFsIGtleSB0aGVtZXMgcHJlc2VudCwgaW5jbHVkaW5nIEROQSByZXBhaXIvCnJlcGxpY2F0aW9uLCB0cmFuc2NyaXB0aW9uL3RyYW5zbGF0aW9uLCBtZXRhYm9saXNtL2NhdGFib2xpc20sIGV4dHJhY2VsbHVsYXIgc3RydWN0dXJlLCBhbmQgY2VsbCBjeWNsZS4gQWxsIG9mIHRoZXNlCnRoZW1lcyBhZ3JlZSB3aXRoIHRoZSBtb2RlbCwgYW5kIGhhdmUgYXBwZWFyZWQgYXMgdG9wIHJlc3VsdHMgaW4gcHJldmlvdXMgYW5hbHlzZXMgKGxpa2UgT1JBIGFuZCB0aHJlc2hvbGRlZCBhbmFseXNpcykuCk1hbnkgb2YgdGhlIGdlbmUgc2V0cyBpZGVudGlmaWVkIGFyZSBjbG9zZWx5IHJlbGF0ZWQgdG8gdGhlc2Ugb3ZlcmFsbCB0aGVtZXM7IGZvciBleGFtcGxlLCAiRE5BIFJFUExJQ0FUSU9OIiwgIkROQSBJUi0KREFNQUdFIEFORCBDRUxMVUxBUiBSRVNQT05TRSIgKHJlcGFpciksICJHMSBTIFRSQU5TSVRJT04iIChjZWxsIGN5Y2xlKSwgIkVVS0FSWU9USUMgVFJBTlNMQVRJT04iLCBhbmQgIkNPTExBR0VOIEZJQlJJTApPUkdBTklaQVRJT04iIChleHRyYWNlbGx1bGFyIG1hdHJpeCBzdHJ1Y3R1cmUpLCBhbW9uZyBvdGhlcnMuIEFtb25nIGFsbCBvZiB0aGVzZSB0aGVtZXMgYW5kIHBhdGh3YXlzLCBub25lIHdlcmUKaWRlbnRpZmllZCBhcyBiZWluZyBub3ZlbC4KCiMjIDQuIEludGVycHJldGF0aW9uCgpXaGVuIGNvbXBhcmluZyB0aGUgcmVzdWx0cyBvZiB0aGUgZW5yaWNobWVudCB0byB0aGUgb3JpZ2luYWwgcGFwZXIsIHdlIHNlZSB0aGF0IHRoZXJlIGFyZSBmZXcgc2ltaWxhcml0aWVzLiBUaGUgcGFwZXIKaWRlbnRpZmllZCBzZXZlcmFsIHBhdGh3YXlzIGFzIGJlaW5nIGVucmljaGVkLCBidXQgdGhlIGZpcnN0IG1ham9yIGRpZmZlcmVuY2UgaXMgdGhhdCB0aGUgYXV0aG9ycyBmb3VuZCB0aGF0ICJhbGwKc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cyB3ZXJlICp1cHJlZ3VsYXRlZCoiIChlbXBoYXNpcyBtaW5lKSwgd2hlcmVhcyBoZXJlLCB0aGUgbWFqb3JpdHkgb2YgZW5yaWNoZWQgcGF0aHdheXMKd2VyZSBmb3VuZCB0byBiZSAqZG93bnJlZ3VsYXRlZCouIFRoZSBzdHVkeSBwbGFjZWQgc2lnbmlmaWNhbnQgZm9jdXMgb24gcGF0aHdheXMgYW5kIGdlbmUgc2V0cyByZWxhdGVkIHRvIHRoZSBpbW11bmUKc3lzdGVtLCBhcyBBRCBoYXMgYmVlbiB0aG91Z2h0IHRvIGJlIGFuIGF1dG9pbW11bmUgZGlzZWFzZSwgYW5kIGZvdW5kIG1hbnkgcGF0aHdheXMgKGUuZy4sIHRoZSBUIGNlbGwgcmVjZXB0b3IKc2lnbmFsbGluZyBwYXRod2F5KSB0byBiZSBlbnJpY2hlZC4gSW4gbXkgZW5yaWNobWVudCwgaW1tdW5lLXJlbGF0ZWQgc2V0cyBkbyBub3QgZG9taW5hdGU7IGluIGZhY3QsIGltbXVuaXR5IGlzIG5vdApldmVuIHByZXNlbnQgYXMgYSBzaWduaWZpY2FudCB0aGVtZS4gSW5zdGVhZCwgdGhlIHJlc3VsdHMgdGVuZCB0byBsZWFuIHRvd2FyZCBtb3JlIGdlbmVyaWMgcGF0aHdheXMuIEZvciBleGFtcGxlLCBzb21lCm9mIHRoZSBtb3N0IHNpZ25pZmljYW50bHkgZW5yaWNoZWQgKGFuZCB1cHJlZ3VsYXRlZCkgc2V0cyB3ZXJlICJlbGVjdHJvbiB0cmFuc3BvcnQgYXRwIiBhbmQgIm9yZ2FuaWMgYWNpZCBjYXRhYm9saWMiLgoKSG93ZXZlciwgdGhlcmUgYXJlIGF0IGxlYXN0IHNvbWUgc2ltaWxhcml0aWVzIHdpdGggdGhlIG9yaWdpbmFsIHBhcGVyLiBGb3IgZXhhbXBsZSwgd2Ugc2VlIHNvbWUgcHJvY2Vzc2VzIHJlbGF0ZWQgdG8KRE5BIHJlcGFpciBhbmQgcmVwbGljYXRpb24gdGhhdCBoYXZlIGJlZW4gZm91bmQgdG8gYmUgZW5yaWNoZWQuIERlc3BpdGUgdGhlIG90aGVyIGRpZmZlcmVuY2VzIGluIHJlc3VsdHMsIHRoaXMgY2FuCnN0aWxsIHN1Z2dlc3QgdGhhdCBBRCBpcyBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGxpbmtlZCB0byB0aGVzZSBtZWNoYW5pc21zLgoKQ29tcGFyaXNvbnMgdG8gdGhlIHRocmVzaG9sZGVkIGFuYWx5c2lzIHBlcmZvcm1lZCBpbiB0aGUgcHJldmlvdXMgcmVwb3J0IGhhdmUgYWxyZWFkeSBiZWVuIGRpc2N1c3NlZCAodGhlIHJlc3VsdHMKc29tZXdoYXQgYWdyZWUpLCBidXQgd2UgY2FuIHJldmlzaXQgaXQgYW55d2F5LiBSZWdhcmRpbmcgdGhlIG51bWJlciBvZiBwYXRod2F5cy9nZW5lIHNldHMgZm91bmQgYnkgZWFjaCBtZXRob2QsIHdlIHNlZQp0aGF0IHRocmVzaG9sZGVkIGFuYWx5c2lzIGZpbmRzIG1vcmUgdXByZWd1bGF0ZWQgcGF0aHdheXMgYW5kIGZld2VyIGRvd25yZWd1bGF0ZWQgcGF0aHdheXMgdGhhbiBlbnJpY2htZW50IGFuYWx5c2lzLApidXQgbWFueSBvZiB0aGUgc3BlY2lmaWMgc2V0cyBjYW4gYmUgZm91bmQgdG8gYmUgcmVsYXRlZCB0byBlYWNoIG90aGVyIGFjcm9zcyBhbmFseXNlcy4gSW4gYWRkaXRpb24sIHRoZSBuZXR3b3JrCnN0cnVjdHVyZXMgcmV2ZWFsIHRoYXQgbWFueSBvZiB0aG9zZSBzZXRzIGFyZSByZWxhdGVkIHRvIGVhY2ggb3RoZXIsIHByb3ZpZGluZyBmdXJ0aGVyIGluc2lnaHQgaW50byB0aGUgZXhwcmVzc2lvbgpwcm9maWxlIG9mIEFELgoKT3ZlcmFsbCwgaXQgc2VlbXMgdGhhdCBpdCBpcyBwb3NzaWJsZSBhbmQgcGVyaGFwcyBldmVuIGxpa2VseSB0aGF0IEkgaGF2ZSBtYWRlIHNvbWUgc21hbGwgbWlzdGFrZXMgaW4gbXkgYW5hbHlzZXMsCmJlY2F1c2UgYXMgSSBwZXJmb3JtIG1vcmUsIHRoZSByZXN1bHRzIGJlY29tZSBpbmNyZWFzaW5nbHkgZGl2ZXJnZW50IGZyb20gdGhlIHJlc3VsdHMgb2YgdGhlIG9yaWdpbmFsIHBhcGVyLiBBZnRlcgpjbGVhbmluZyBhbmQgbm9ybWFsaXppbmcgdGhlIGRhdGFzZXQsIHJlc3VsdHMgd2VyZSBmYWlybHkgaW4gbGluZSB3aXRoIHRoZSBvcmlnaW5hbCBzdHVkeSwgYnV0IGFzIHRoZSBwcm9jZXNzZXMgYmVnYW4KdG8gYnVpbGQgdXAgZnJvbSBlYWNoIG90aGVyLCByZXN1bHRzIGJlZ2FuIHRvIGRpZmZlci4gRm9yIGV4YW1wbGUsIGFmdGVyIGNvbmR1Y3RpbmcgdGhlIHRocmVzaG9sZGVkIG92ZXItcmVwcmVzZW50YXRpb24KYW5hbHlzaXMsIEkgY291bGQgb25seSBjb25jbHVkZSB0aGF0IHRoZSByZXN1bHRzIHdlcmUgcGFydGlhbGx5IHN1cHBvcnRlZCBieSB0aGUgb3JpZ2luYWwgc3R1ZHkuIE5vdyBhZnRlciB0aGUgbm9uLQp0aHJlc2hvbGRlZCBhbmFseXNpcywgZXZlbiBmZXdlciByZXN1bHRzIGNhbiBiZSBzdXBwb3J0ZWQuIEl0IHdvdWxkIHByb2JhYmx5IGJlIGEgZ29vZCBpZGVhIHRvIHJldmlzaXQgZWFjaCBvZiB0aGUKcHJldmlvdXMgc3RlcHMgYW5kIHRyeSB0byByZXBsaWNhdGUgdGhlIHN0dWR5J3MgcmVzdWx0cy4KCkZyb20gdGhlIE9SQSByZXBvcnQsIHdlIGtub3cgdGhhdCBbQG9rYV0sIFtAcGFuemVyXSwgYW5kIFtAbWFuc291cmldIGFsbCBzdXBwb3J0IHRoZSBmaW5kaW5ncyBvZiB0aGUgdGhyZXNob2xkZWQKYW5hbHlzaXMgKElMLTE5LCBUTFI0LCBhbmQgdGhlIGVmZmVjdHMgb2YgZHVwaWx1bWFiIGFuZCBjeWNsb3Nwb3JpbmUsIHJlc3BlY3RpdmVseSkgYW5kIHRoZSBvcmlnaW5hbCBwYXBlciwgYnV0IHNpbmNlCnRoZSBlbnJpY2htZW50IGFuYWx5c2lzIGRvZXMgbm90IGNvbXBsZXRlbHkgZGlzYWdyZWUgd2l0aCB0aGUgc3R1ZHksIHdlIGNhbiBzdGlsbCBmaW5kIGFkZGl0aW9uYWwgc291cmNlcyB0byBzdXBwb3J0CnNvbWUgb2YgdGhlIHBhdGh3YXlzL2dlbmUgc2V0cy4gRm9yIGV4YW1wbGUsIHNvbWUgc2V0cyB3ZXJlIGZvdW5kIHRvIGJlIHJlbGF0ZWQgdG8gdmlyYWwgRE5BIHJlcGxpY2F0aW9uLiBBIHN0dWR5IGJ5CltAd29sbGVuYmVyZ10gZm91bmQgdGhhdCBBRCBwYXRpZW50cyBtYXkgYmUgbW9yZSB2dWxuZXJhYmxlIHRvIHNwZWNpZmljIHR5cGVzIG9mIHZpcmFsIGluZmVjdGlvbnMsIGFuZCBnaXZlcyBhIHBvc3NpYmxlCm1lY2hhbmlzbSwgcmVsYXRlZCB0byBETkEgcmVwbGljYXRpb24gaW4gdGhlIHBhdGllbnQsIGFzIGV4cGxhbmF0aW9uLiBJbiBhZGRpdGlvbiwgdGhlIG1ham9yIHRoZW1lIG9mIEROQSByZXBhaXIgaXMKc3VwcG9ydGVkIGJ5IFtAa2FyYW1hbl0sIHdoaWNoIGZvdW5kIHRoYXQgImluY3JlYXNlZCBjaHJvbW9zb21lIGluc3RhYmlsaXR5IFtpbiByZWxhdGlvbiB0byB0aGUgRE5BIHJlcGFpciBvZiBBRApwYXRpZW50c10gbWF5IHBsYW4gYW4gaW1wb3J0YW50IHJvbGUgaW4gdGhlIGV0aW9sb2d5IG9mIEFEIi4gU28gZGVzcGl0ZSBteSBlbnJpY2htZW50IHJlc3VsdHMgbm90IGNvbXBsZXRlbHkgYWdyZWVpbmcKd2l0aCBbQG1vYnVzXSwgdGhlIHByb2Nlc3MgZGlkIGZpbmQgc3VwcG9ydCBpbiBvdGhlciBwdWJsaXNoZWQgYXJ0aWNsZXMgZm9yIHNvbWUgb3RoZXIgcG9zc2libHkgcmVsYXRlZCBjb25jZXB0cy4KCiMjIDUuIERydWdCYW5rIFBvc3QtQW5hbHlzaXMKClRoZSBmaW5hbCBwYXJ0IG9mIHRoZSBhbmFseXNpcyB3aWxsIGJlIHRvIHJ1biBhIHBvc3QtYW5hbHlzaXMgb24gdGhlIG1haW4gZW5yaWNobWVudCBuZXR3b3JrIHVzaW5nIERydWdCYW5rLiBXZSBrbm93CmZyb20gdGhlIG9yaWdpbmFsIHN0dWR5IFtAbW9idXNdIHRoYXQgdGhlIGRydWdzIGR1cGlsdW1hYiBhbmQgY3ljbG9zcG9yaW5lIGNhbiBiZSB1c2VkIHRvIGVmZmVjdGl2ZWx5IHRyZWF0IEFELCB3aGljaAppcyBhZGRpdGlvbmFsbHkgc3VwcG9ydGVkIGJ5IFtAbWFuc291cmldIGFuZCBbQGFyaWVuc10sIHNvIGl0IHdvdWxkIGJlIGFwcHJvcHJpYXRlIHRvIHRyeSBydW5uaW5nIGEgcG9zdC1hbmFseXNpcwpvbiB0aGUgcHJpbWFyeSBlbnJpY2htZW50IG1hcCB0byBkZXRlcm1pbmUgaWYgaXQgY2FuIGJlIHZlcmlmaWVkIGhlcmUuCgpGaXJzdCwgd2Ugd2lsbCBkb3dubG9hZCB0aGUgRkRBLWFwcHJvdmVkIERydWdCYW5rIGRhdGFzZXQgZm9yIGh1bWFuIHVzZSAodGhpcyBHTVQgZmlsZSBpcyB0YXJnZXRlZCBiZWNhdXNlIHdlIGFscmVhZHkKa25vdyB0aGF0IGR1cGlsdW1hYiBhbmQgY3ljbG9zcG9yaW5lIGhhdmUgYmVlbiBhcHByb3ZlZCBmb3IgdXNlIGluIHRyZWF0aW5nIEFEKS4gVGhpcyBjYW4gYmUgZG9uZSBpbiBhIHZlcnkgc2ltaWxhcgpmYXNoaW9uIGFzIHRvIGhvdyB0aGUgR1NFQSBnZW5lIHNldCB3YXMgZG93bmxvYWRlZCBmcm9tIHRoZSBCYWRlciBMYWIgcHJldmlvdXNseTsgdGhlIGZvbGxvd2luZyBzbmlwcGV0IGFjY29tcGxpc2hlcwpleGFjdGx5IHRoYXQuIEFsdGVybmF0aXZlbHksIHNpbmNlIHRoZSBwb3N0LWFuYWx5c2lzIHdpbGwgYmUgcnVuIGxvY2FsbHksIGl0IGNhbiBhbHNvIGJlIGRvd25sb2FkZWQgZGlyZWN0bHkgZnJvbQp3aXRoaW4gQ3l0b3NjYXBlIGJ5IGxvYWRpbmcgdGhlIHNpZ25hdHVyZSBnZW5lIHNldCBmcm9tIHRoZSB3ZWIuCgpgYGAge3IsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCByZXN1bHRzID0gImhpZGUifQojIEdldCBhIGxpc3Qgb2YgYWxsIHRoZSBhdmFpbGFibGUgZ2VuZSBzZXQgZmlsZXMKZ3NVcmwgPC0gImh0dHA6Ly9kb3dubG9hZC5iYWRlcmxhYi5vcmcvRU1fR2VuZXNldHMvY3VycmVudF9yZWxlYXNlL0h1bWFuL3N5bWJvbC9EcnVnVGFyZ2V0cy8iCmZpbGVzIDwtIFJDdXJsOjpnZXRVUkwoZ3NVcmwpCmNvbm4gPC0gdGV4dENvbm5lY3Rpb24oZmlsZXMpCmNvbnRlbnRzIDwtIHJlYWRMaW5lcyhjb25uKQpjbG9zZShjb25uKQoKIyBDaGFuZ2VkIHRoZSByZWdleCB0byBsb29rIGZvciAiYXBwcm92ZWQiIGRydWdzCnJlZ2V4IDwtIGdyZWdleHByKCIoPzw9PGEgaHJlZj1cIikoLiouYXBwcm92ZWQuKi4pKC5nbXQpKD89XCI+KSIsIGNvbnRlbnRzLCBwZXJsID0gVFJVRSkKZ210IDwtIHVubGlzdChyZWdtYXRjaGVzKGNvbnRlbnRzLCByZWdleCkpCgojIERvd25sb2FkIHRoZSBmaWxlIGlmIGl0IGhhcyBub3QgYmVlbiBkb3dubG9hZGVkIGFscmVhZHkKZ210RmlsZSA8LSBmaWxlLnBhdGgoZ2V0d2QoKSwgZ210KQppZiAoIWZpbGUuZXhpc3RzKGdtdEZpbGUpKSB7CiAgZG93bmxvYWQuZmlsZShwYXN0ZShnc1VybCwgZ210LCBzZXAgPSAiIiksIGRlc3RmaWxlID0gZ210RmlsZSkKfQpgYGAKCldlIHdpbGwgYmVnaW4gd2l0aCBhIHRhcmdldGVkIGFwcG9yYWNoLCB1c2luZyBvbmx5IHRoZSBrbm93biBzaWduYXR1cmVzIG9mIHRoZXNlIHR3byBkcnVncy4gQSBjb3B5IG9mIHRoZSBHTVQgZmlsZSB3YXMKbWFkZSwgYW5kIGFsbCBsaW5lcyBvdGhlciB0aGFuIGR1cGlsdW1hYiBhbmQgY3ljbG9zcG9yaW5lIHdlcmUgcmVtb3ZlZC4gVGhpcyB3YXMgbG9hZGVkIGFzIHRoZSBzaWduYXR1cmUgc2V0IGluCkN5dG9zY2FwZSwgYW5kIHRoZSBwb3N0LWFuYWx5c2lzIHdhcyBydW4gd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMgKE1hbm4tV2hpdG5leSBUd28tU2lkZWQgdGVzdCB3aXRoIGN1dG9mZiAwLjA1KS4gVGhlCnJlc3VsdCB3YXMgdGhhdCBuZWl0aGVyIG9mIHRoZSB0d28gZHJ1Z3Mgd2VyZSBhYmxlIHRvIHBhc3MuIER1cGlsdW1hYiBoYWQgYSBmaW5hbCBwLXZhbHVlIG9mIDAuMTgzMiBhbmQgb3ZlcmxhcCBvZiAxLAphbmQgY3ljbG9zcG9yaW5lIGhhZCBhIHAtdmFsdWUgb2YgMC44ODQ0IGFuZCBvdmVybGFwIG9mIDEuIFRoaXMgc3VnZ2VzdHMgdGhhdCBlaXRoZXIgdGhlc2UgZHJ1Z3Mgc2hvdWxkIG5vdCBiZQpzaWduaWZpY2FudGx5IGVmZmVjdGl2ZSBpbiB0cmVhdGluZyBBRCwgb3IgdGhlcmUgbWF5IGJlIGFuIGlzc3VlIHdpdGggdGhlIGVucmljaG1lbnQgbWFwOyB0aGUgbGF0dGVyIGlzIG1vcmUgbGlrZWx5LApiZWNhdXNlIG9mIHRoZSBmYWN0IHRoYXQgdGhlIGRydWdzIGhhdmUgYWxyZWFkeSBiZWVuIGFwcHJvdmVkIGZvciB1c2UuIFBlcmhhcHMgdGhpcyByZXN1bHQgaXMgbm90IHRvbyBzdXJwcmlzaW5nLApjb25zaWRlcmluZyB0aGUgcmVzdWx0cyBvZiB0aGUgZW5yaWNobWVudCBhbmFseXNpcyBjb21wYXJlZCB0byB0aGUgb3JpZ2luYWwgcGFwZXIgKHNlZSB0aGUgSW50ZXJwcmV0YXRpb24gc2VjdGlvbiBhYm92ZQpmb3IgbW9yZSBkZXRhaWxzKSwgYnV0IGl0IG1heSBzdGlsbCBiZSBpbnRlcmVzdGluZyB0byBjb25kdWN0IGFuIGFkZGl0aW9uYWwgZXhwbG9yYXRvcnkgc2lnbmF0dXJlIGFuYWx5c2lzIHRvIHNlZSB3aGF0Cm90aGVyIGRydWdzIG1heSBoYXZlIHNpbWlsYXIgZWZmZWN0cy4KClJ1bm5pbmcgdGhlIHBvc3QtYW5hbHlzaXMgd2l0aCBkZWZhdWx0IHNldHRpbmdzIGFuZCB0aGUgZW50aXJlIERydWdCYW5rIEdNVCBmaWxlIChub3QganVzdCBmaWx0ZXJlZCB0byBkdXBpbHVtYWIgYW5kCmN5Y2xvc3BvcmluZSkgeWllbGRlZCA2OCByZXN1bHRzLCB3aGljaCBtYWRlIHRoZSByZXN1bHRpbmcgbWFwIHRvbyBjbHV0dGVyZWQuIFRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHJlc3VsdHMsIHRoZQpjdXRvZmYgd2FzIHJlZHVjZWQgdG8gMC4wMSwgd2hpY2ggeWllbGRlZCAxMyByZXN1bHRzLCBhIGZhciBtb3JlIG1hbmFnZWFibGUgYW1vdW50LgoKIVtdKGZpZ3VyZXMvcGFfZXhwbG9yZS5wbmcpCgpUYWJsZSAzLiBUaGUgbGlzdCBvZiAxMyBkcnVncyB0aGF0IHBhc3NlZCB0aGUgTWFubi1XaGl0bmV5IHRlc3QgZm9yIGN1dG9mZiAwLjAxLgoKTG9va2luZyBvdmVyIHRoaXMgbGlzdCBvZiBkcnVncywgd2Ugc2VlIG1hbnkgImdlbmVyaWMiIGNvbXBvdW5kcyBsaWtlIE5BREggYW5kIHppbmMsIHdoaWNoIHdlIGNhbiBhbHJlYWR5IGd1ZXNzCnByb2JhYmx5IGRvIG5vdCBoZWxwIGluIHRoZSB0cmVhdG1lbnQgb2YgQUQuIEFnYWluLCB0aGlzIGlzIGxpa2VseSBkdWUgdG8gYSBwb29yIGVucmljaG1lbnQgbWFwIGNvbnN0cnVjdGlvbiwgd2hlcmUKbWFueSBub2RlcyBhcmUgYWJsZSB0byBhY2hpZXZlIGhpZ2hlciBsZXZlbHMgb2Ygb3ZlcmxhcCBqdXN0IGJlY2F1c2UgdGhlIG1vc3Qgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBnZW5lIHNldHMgYXJlCm5vdCBzcGVjaWZpYyB0byBBRC4gVGhlIGZvbGxvd2luZyB0d28gZmlndXJlcyBzaG93IHRoZSBzaWduYXR1cmUgZHJ1ZyBzZXQgb24gdG9wIG9mIHRoZSBleGlzdGluZyBlbnJpY2htZW50IG1hcCwgd2hpY2gKbWF5IGhlbHAgdG8gc2hvdyB3aGljaCBwYXJ0aWN1bGFyIHNldHMgaGF2ZSBjb25uZWN0aW9ucyB0byBzcGVjaWZpYyBkcnVncy4KCiFbXShmaWd1cmVzL3BhX2FsbC5wbmcpCgpGaWd1cmUgNi4gVGhlIHNpZ25hdHVyZSBzZXQgb3ZlcmxheWVkIG9udG8gdGhlIGVudGlyZSBtYWluIGVucmljaG1lbnQgbWFwLgoKIVtdKGZpZ3VyZXMvcGFfb3ZlcmxhcC5wbmcpCgpGaWd1cmUgNy4gTm9kZXMgaW4gdGhlIGVucmljaG1lbnQgbWFwIHRoYXQgaGF2ZSBubyBjb25uZWN0aW9ucyB0byBhbnkgbm9kZSBpbiB0aGUgc2lnbmF0dXJlIHNldCBoYXZlIGJlZW4gcmVtb3ZlZC4gVGhlCmxhYmVscyBvZiB0aGUgbm9kZXMgaW4gdGhlIHNpZ25hdHVyZSBzZXQgbWF5IGJlIHRvbyBzbWFsbCB0byByZWFkIGhlcmUsIHNvIGl0IG1heSBiZSBoZWxwZnVsIHRvIHZpZXcgdGhlIGltYWdlCnNlcGFyYXRlbHkuCgojIyA2LiBSZWZlcmVuY2VzCg==